(function () {
	$(document).ready(function () {
		$('html').add('body').addClass('ij-fullscreen');
	});
	
	window.ij = {};
	ij.version = "0.0.1 alpha";
	ij.namespace = function (namespace) {
		if (namespace) {
			var parts = namespace.split('.');
			var ns = window; 
			for (var i = 0; i < parts.length; i++) {
				if (typeof ns[parts[i]] === 'undefined') {
					ns[parts[i]] = {};
				}
				ns = ns[parts[i]];
			}
			ns.namespaceString = namespace;
			return ns;
		}
		
		return null;
	};
	ij.pkg = function (pkg) {
		return ij.namespace('ij.'+pkg);
	};
	ij.apply = function (object, applies, overwrite_existing) {
		for (var name in applies) {
			if (typeof object[name] == 'undefined' || overwrite_existing !== false) {
				object[name] = applies[name];
			}
		}
		
		return object;
	};
	ij.applyIf = function (object, applies) {
		return ij.apply(object, applies, false);
	};
	ij.clone = function (object) {
		return ij.apply({}, object);
	};
	ij.each = function (obj, callback, scope) {
		if (obj instanceof Array) {
			for (var i = 0; i < obj.length; i++) {
				if (callback.call(scope || obj, i, obj[i]) === false) {
					break;
				};
			};
		} else if (obj instanceof Object) {
			for (var name in obj) {
				if (callback.call(scope || obj, name, obj[name]) === false) {
					break;
				};
			};
		};
		
		return this;
	};
	ij.mapSkipFlag = {};
	ij.map = function (obj, callback, scope) {
		var res = [];
		ij.each(obj,function (i, item) {
			var cres = callback.call(scope || obj, i, item);
			if (cres != ij.mapSkipFlag) {
				res.push(callback.call(scope || obj, i, item));
			}
		},this);
		
		return res;
	};
	ij.mapObject = function (obj, callback, scope) {
		var res = {};
		ij.each(obj,function (i, item) {
			var cres = callback.call(scope || obj, i, item);
			if (cres != ij.mapSkipFlag) {
				ij.apply(res, cres);
			}
		},this);
		
		return res;
	};
	ij.load = function (url, callback, scope) {
		$.ajax({
			url: url,
			type: 'GET',
			dataType: 'json',
			success: function (data) {
				callback.call(scope || window, data);
			},
			error: function () {
				callback.call(scope || window, null);
			}
		});
	};
	ij.loadAndExecute = function (url, callback, scope) {
		ij.load(url, function (data) {
			var objs = [];

			data = (data instanceof Array)?data:[data];
			data.each(function (i, item) {
				objs.push(new (ij.namespace(item.classname))(item));
			});
			
			callback.call(scope || window, objs);
		});
	};
	
	ij.pkg('core');
	ij.core.Class = function(){};
	ij.core.Class.extend = function(prop) {
		var _super = this.prototype;
		   
	    var prototype = new this(false),
	    fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;;
		   
	    for (var name in prop) {
	    	prototype[name] = typeof prop[name] == "function" &&
	        typeof _super[name] == "function" && fnTest.test(prop[name]) ?
	        (function(name, fn){
	        	return function() {
	        		var tmp = this._super;
		            this._super = _super[name];
		            var ret = fn.apply(this, arguments);       
		            this._super = tmp;
		            return ret;
	        	};
	        })(name, prop[name]) :
	        prop[name];
	    }
		
	    function Class() {
	    	if ( (arguments.length == 0 || arguments[0] !== false) && this.init ) {
	    		this.init.apply(this, arguments);
	    	}
	    }
		   
	    Class.prototype = prototype;
	    Class.fn = Class.prototype;
	    Class.prototype.constructor = Class;
	   	Class.extend = arguments.callee;
	    return Class;
	};
})();

